﻿//*** Guidance generated code ***//
using System;
using System.Collections.Generic;
using System.Linq;

using ProjectBase.Core;

using $prjsn$.Entity;
using $prjsn$.Common;
using $prjsn$.Common.Validation;

namespace $safeprojectname$
{
    public class AdditionalValueTypeRule<TItem, TValue> : ValueTypeNullableRule<TItem, TValue>
        where TItem : class, IBusinessObject
        where TValue : struct, IComparable<TValue>
    {
        #region members

        private IField _field;

        #endregion members

        #region Constructor

        public AdditionalValueTypeRule(Func<TItem, TValue?> compiledExpression, IField field)
            : base(compiledExpression, field.PropertyName)
        {
            _field = field;
        }

        #endregion Constructor

        #region Validate

        public override ValidationResult Validate(TItem item, out ValidationMessage message)
        {
            message = null;

            // item cannot be null
            if (item.IsNull())
            {
                message = new ValidationMessage(Str.Messages.NullInsteadOfEntityProvided1)
                {
                    EntityName,
                };
                return ValidationResult.Error;
            }

            var result = CompiledExpression.Invoke(item);
            var entity = item as IPersistentObject;
            var itemId = entity.IsNull()
                ? "N/A"
                : entity.IsTransient() ? "new" : entity.IDToDisplay;

            // NOT Required string could be null or empty
            if (!result.HasValue)
            {
                if (!IsRequired)
                {
                    return ValidationResult.IsValid;
                }

                message = new ValidationMessage(Str.Messages.MissingProperty2)
                {
                    itemId,
                    PropertyName,
                };
                return ValidationResult.Error;
            }

            // is too short
            var isShorter = MinValue.CompareTo(result.Value) > 0;
            if (isShorter)
            {
                message = new ValidationMessage(Str.Messages.ValueTooLow4)
                {
                    PropertyName.GetLocalized(EntityName),
                    itemId,
                    result.Value,
                    MinValue,
                };
                return ValidationResult.Error;
            }

            // is too long
            var isLonger = MaxValue.CompareTo(result.Value) < 0;
            if (isLonger)
            {
                message = new ValidationMessage(Str.Messages.ValueTooHigh4)
                {
                    PropertyName.GetLocalized(EntityName),
                    itemId,
                    result.Value,
                    MaxValue,
                };
                return ValidationResult.Error;
            }

            return ValidationResult.IsValid;
        }

        #endregion Validate

        #region properties

        protected virtual IField Field
        {
            get { return _field; }
            set { _field = value; }
        }

        #endregion properties
    }
}